package com.lcq.httplib.client.adapter;

import com.lcq.httplib.ErrorEnum;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
import okhttp3.ResponseBody;

public abstract class AbsCallAdapter<T> implements ICallAdapter {
    protected final RequestParams<T> requestParams;
    protected final Call call;

    public AbsCallAdapter(RequestParams<T> requestParams) {
        this.requestParams = requestParams;
        this.call = createOkHttpCall();
    }

    public void call() {
        if (requestParams.isAsync()) {
            call.enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    callbackFail(ErrorEnum.NET_FAIL);
                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) {
                    handleResponse(response);
                }
            });
        } else {
            try {
                Response response = call.execute();
                handleResponse(response);
            } catch (IOException e) {
                e.printStackTrace();
                callbackFail(ErrorEnum.NET_FAIL);
            }
        }
    }

    private void handleResponse(Response response) {
        if (!response.isSuccessful()) {
            requestParams.getCallback().onFail(response.code(), response.message());
            return;
        }

        ResponseBody responseBody = response.body();
        if (responseBody == null) {
            callbackFail(ErrorEnum.BODY_NULL);
            return;
        }

        handleSuccessBody(responseBody);
    }

    protected void callbackFail(ErrorEnum errorEnum) {
        requestParams.getCallback().onFail(errorEnum.getCode(), errorEnum.getMsg());
    }

    public void cancel() {
        call.cancel();
    }

    abstract protected Call createOkHttpCall();

    abstract protected void handleSuccessBody(ResponseBody responseBody);
}
